package com.feiyu.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.feiyu.order.dao.GoodsDao;
import com.feiyu.order.dao.LeaseOrderDao;
import com.feiyu.order.dao.LogisticsInfoDao;
import com.feiyu.order.dao.ShopDao;
import com.feiyu.order.dto.*;
import com.feiyu.order.entity.GoodsEntity;
import com.feiyu.order.entity.LeaseOrderEntity;
import com.feiyu.order.entity.LogisticsInfoEntity;
import com.feiyu.order.entity.ShopEntity;
import com.feiyu.order.feign.LogisticsFeign;
import com.feiyu.order.feign.PaymentAndCreditFeign;
import com.feiyu.order.service.OrderInfoService;
import com.feiyu.order.service.OrderService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: Doate
 * @Date: Created in 2021/4/9 15:38
 * @Description:
 */

@Service
public class OrderServiceImpl implements OrderService {

    @Resource
    LogisticsFeign logisticsFeign;

    @Resource
    OrderInfoService orderInfoService;

    @Resource
    PaymentAndCreditFeign paymentAndCreditFeign;

    @Resource
    GoodsDao goodsDao;

    @Resource
    LeaseOrderDao leaseOrderDao;

    @Resource
    LogisticsInfoDao logisticsInfoDao;

    @Resource
    ShopDao shopDao;


    @Override
    public void add() {
        LeaseOrderEntity orderEntity = new LeaseOrderEntity();
        orderEntity.setOrderId("20210417215139000002");
        leaseOrderDao.insert(orderEntity);
    }

    @Override
    public Map<String, Object> createOrder(createOrderDto dto) {

        Map<String, Object> data = new HashMap<>();
        String orderId = createOrderId();

        LeaseOrderEntity orderEntity = setLeaseOrderInfo(dto);
        orderEntity.setOrderId(orderId);
        leaseOrderDao.insert(orderEntity);

        //获取店铺地址
        QueryWrapper<ShopEntity> shopEntityQueryWrapper = new QueryWrapper<>();
        shopEntityQueryWrapper.eq("user_id",dto.getShopId());
        ShopEntity shoInfo = shopDao.selectOne(shopEntityQueryWrapper);
        dto.setStartAddress(shoInfo.getShopAddress());

        //创建物流订单
        LogisticsInfoEntity logisticsInfoEntity = setLogisticsInfo(dto);
        logisticsInfoEntity.setOrderId(orderId);

        int sendId = logisticsFeign.addLogisticsOrder(logisticsInfoEntity);
        orderEntity.setLogisticsSendId(sendId);
        UpdateWrapper<LeaseOrderEntity> wrapper = new UpdateWrapper<>();
        wrapper.eq("order_id", orderId);
        leaseOrderDao.update(orderEntity, wrapper);

        //扣除买家费用
        PaymentDto paymentDto = setPayment(orderEntity.getBuyerId(), -orderEntity.getOrderCost(),
                "订单" + orderId + " 押金与租赁费用支出", 10);
        paymentAndCreditFeign.payAmount(paymentDto);

        //商品数量改变
        updateGoodsNum(orderEntity.getGoodsId(), -orderEntity.getOrderNum());

        return data;
    }

    public PaymentDto setPayment(int userId, float pay, String intro, int powerLv) {

        PaymentDto paymentDto = new PaymentDto();
        paymentDto.setDealAmount(pay);
        paymentDto.setUserId(userId);
        paymentDto.setPowerLv(powerLv);
        paymentDto.setMinorTrader("飞鱼商城平台");
        paymentDto.setDealIntro(intro);

        return paymentDto;
    }

    //创建订单号
    int timer = 0;

    public String createOrderId() {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        formatter.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        String str = formatter.format(new Date());
        String s = String.format("%06d", timer++);
        return str + s;
    }

    //设置租赁订单信息
    public LeaseOrderEntity setLeaseOrderInfo(createOrderDto dto) {
        LeaseOrderEntity entity = new LeaseOrderEntity();

        entity.setShopId(dto.getShopId());
        entity.setBuyerId(dto.getBuyerId());
        entity.setGoodsId(dto.getGoodsId());
        entity.setOrderNum(dto.getGoodsNum());
        entity.setOrderCost(dto.getOrderCost());
        entity.setOrderCreatTime(new Date());
        entity.setOrderStartTime(dto.getOrderStartTime());
        entity.setOrderEndTime(dto.getOrderEndTime());
        entity.setOrderLeaseTime(dto.getOrderLeaseTime());

        QueryWrapper<GoodsEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("goods_id", dto.getGoodsId());
        GoodsEntity goodsInfo = goodsDao.selectOne(wrapper);

        entity.setTimeMode(goodsInfo.getGoodsTimeMode());
        entity.setGoodsPostageMode(goodsInfo.getGoodsPostageMode());

        return entity;
    }

    //设置发货物流订单信息
    public LogisticsInfoEntity setLogisticsInfo(createOrderDto dto) {
        LogisticsInfoEntity entity = new LogisticsInfoEntity();
        entity.setStartAddress(dto.getStartAddress());
        entity.setEndAddress(dto.getEndAddress());

        //模拟与物流公司下单，创建运输物流单号
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        formatter.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        String str = formatter.format(new Date());
        int ran = new Random().nextInt(100);
        String logisticsNo = "MMWL" + str + String.format("%02d", ran);
        entity.setLogisticsNo(logisticsNo);


        return entity;
    }


    @Override
    public Map<String, Object> searchByParam(selectOrderDto dto, int power, int userId) {

        //设置筛选条件
        QueryWrapper<LeaseOrderEntity> con = new QueryWrapper<>();

        if (power > 9) {
            if (power == 10) {
                con.eq("buyer_id", userId);
                if (dto.getShopId() != null) {
                    con.eq("shop_id", dto.getShopId());
                }
            } else if (power <= 20) {
                con.eq("shop_id", userId);
                if (dto.getBuyerId() != null) {
                    con.eq("buyer_id", dto.getBuyerId());
                }
            } else {
                return null;
            }
        } else {
            if (dto.getBuyerId() != null) {
                con.eq("buyer_id", dto.getBuyerId());
            }
            if (dto.getShopId() != null) {
                con.eq("shop_id", dto.getShopId());
            }
        }

        if (dto.getOrderState() != null) {
            con.eq("order_state", dto.getOrderState());
        }

        //设置分页查询
        Map<String, Object> data = new HashMap<>();
        IPage<LeaseOrderEntity> iPage = leaseOrderDao.selectPage(new Page<LeaseOrderEntity>(dto.getPage(), dto.getLimit()), con);
        List<LeaseOrderEntity> records = iPage.getRecords();

        data.put("totalCount", iPage.getTotal());
        data.put("pageSize", iPage.getSize());
        data.put("totalPage", iPage.getPages());
        data.put("currPage", iPage.getCurrent());

        //封装更多信息
        List<Map<String, Object>> list = new ArrayList<>();
        for (LeaseOrderEntity key : records) {
            list.add(getMoreOrderInfo(key));
        }
        data.put("list", list);

        return data;
    }

    @Override
    public Map<String, Object> searchById(String orderId) {
        Map<String, Object> data = new HashMap<>();
        if (orderId.equals("")) {
            return data;
        }
        QueryWrapper<LeaseOrderEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", orderId);
        LeaseOrderEntity entity = leaseOrderDao.selectOne(wrapper);
        if (entity != null) {
            data = getMoreOrderInfo(entity);
        }

        return data;
    }

    //获取更多订单信息
    public Map<String, Object> getMoreOrderInfo(LeaseOrderEntity entity) {

        Map<String, Object> data = new HashMap<>();

        if (entity == null) {
            return data;
        }

        BeanUtil.copyProperties(entity, data);

        GoodsEntity goodsInfo = getGooods(entity.getGoodsId());

        if (goodsInfo != null) {

            Map<String, Object> goods = new HashMap<>();
            BeanUtil.copyProperties(goodsInfo, goods);
            String img = goods.get("goodsImages").toString();
            goods.remove("goodsImages");
            goods.put("goodsImages", getImageUrl(img));

            data.put("goods", goods);
        }

        //获取物流订单信息
        if (entity.getLogisticsSendId() != null) {
            Map<String, Object> send = logisticsFeign.searchById(entity.getLogisticsSendId());
            data.put("send", send);
        }
        if (entity.getLogisticsBackId() != null) {
            Map<String, Object> back = logisticsFeign.searchById(entity.getLogisticsSendId());
            data.put("back", back);
        }

        return data;
    }

    //商品图片获取
    public Map<String, Object> getImageUrl(String goodsImages) {

        Map<String, Object> goodInfoImages = new HashMap<>();
        String[] split = goodsImages.split(";");
        String url = "https://test-wanghanbin.oss-cn-hangzhou.aliyuncs.com/feiyuImages/";
        for (int i = 0; i < split.length; i++) {
            goodInfoImages.put("goodImage_" + (i + 1), url + split[i]);
        }
        return goodInfoImages;
    }

    //获取商品信息
    public GoodsEntity getGooods(int goodsId) {
        QueryWrapper<GoodsEntity> wrapper_goods = new QueryWrapper<>();
        wrapper_goods.eq("goods_id", goodsId);
        GoodsEntity goodsInfo = goodsDao.selectOne(wrapper_goods);
        return goodsInfo;
    }

    //更新商品数量
    public boolean updateGoodsNum(int goodsId, int var) {
        UpdateWrapper<GoodsEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("goods_id", goodsId);

        GoodsEntity goodsInfo = new GoodsEntity();
        goodsInfo.setGoodsNums(getGooods(goodsId).getGoodsNums() + var);

        goodsDao.update(goodsInfo, updateWrapper);

        return true;
    }

    //买家签收
    @Override
    public boolean buyerReceiveGoods(operateOrderDto dto, int userId) {

        LeaseOrderEntity orderEntity = orderInfoService.getOrderInfo(dto.getOrderId());
        UpdateWrapper<LeaseOrderEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_id", dto.getOrderId());

        if (dto.getCargoState() == 1) {
            //损坏时,需要平台与物流单位协商后做出赔偿
            orderEntity.setOrderState(11);

            GoodsEntity goodsInfo = getGooods(orderEntity.getGoodsId());
            float indemnity = goodsInfo.getGoodsPrice() * orderEntity.getOrderNum();

            PaymentDto paymentDto = setPayment(orderEntity.getShopId(), indemnity, "订单" + orderEntity.getOrderId() + "物流损坏赔偿", 11);
            paymentAndCreditFeign.payAmount(paymentDto);

        } else if (dto.getCargoState() == 0) {
            //完好
            orderEntity.setOrderState(3);
        }

        //更新订单状态
        leaseOrderDao.update(orderEntity, updateWrapper);

        LogisticsDto logisticsDto = new LogisticsDto();
        logisticsDto.setLogisticsId(orderEntity.getLogisticsSendId());
        logisticsDto.setState(dto.getCargoState());

        logisticsFeign.receiveGoods(logisticsDto);

        return false;
    }

    //卖家签收
    @Override
    public boolean shopReceiveGoods(operateOrderDto dto, int userId) {

        LeaseOrderEntity orderEntity = orderInfoService.getOrderInfo(dto.getOrderId());
        UpdateWrapper<LeaseOrderEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_id", dto.getOrderId());
        orderEntity.setOrderState(7);
        GoodsEntity goodsInfo = getGooods(orderEntity.getGoodsId());


        if (dto.getCargoState() == 1) {
            //损坏时,需要平台与物流单位协商后做出赔偿

            float indemnity = goodsInfo.getGoodsPrice() * orderEntity.getOrderNum();

            PaymentDto paymentDto = setPayment(orderEntity.getShopId(), indemnity, "订单" + orderEntity.getOrderId() + "物流损坏赔偿", 11);
            paymentAndCreditFeign.payAmount(paymentDto);

        } else if (dto.getCargoState() == 0) {
            //商品库存恢复
            updateGoodsNum(orderEntity.getGoodsId(), orderEntity.getOrderNum());
        }

        //租赁费用 与 押金（存在免押金的情况）
        float sumRent = goodsInfo.getGoodsRent() * orderEntity.getOrderNum();
        float sumDeposit = orderEntity.getOrderCost() - sumRent;

        //买家押金返还
        if (sumDeposit > 0) {
            PaymentDto paymentDto = setPayment(orderEntity.getBuyerId(), sumDeposit,
                    "订单" + orderEntity.getOrderId() + " 押金返还", 10);
            paymentAndCreditFeign.payAmount(paymentDto);
        }

        //卖家获取租赁费用
        if (sumRent > 0) {
            PaymentDto paymentDto = setPayment(orderEntity.getShopId(), sumRent,
                    "订单" + orderEntity.getOrderId() + " 租金收入", 11);
            paymentAndCreditFeign.payAmount(paymentDto);
        }


        //更新订单状态
        leaseOrderDao.update(orderEntity, updateWrapper);

        LogisticsDto logisticsDto = new LogisticsDto();
        logisticsDto.setLogisticsId(orderEntity.getLogisticsBackId());
        logisticsDto.setState(dto.getCargoState());
        logisticsFeign.receiveGoods(logisticsDto);

        //更新租户的信用值
        paymentAndCreditFeign.updateBuyerCreditScore(orderEntity.getOrderId());

        return true;
    }

    //租户归还商品
    @Override
    public boolean rebackGoods(String orderId) {

        LeaseOrderEntity orderInfo = orderInfoService.getOrderInfo(orderId);
        orderInfo.setOrderState(4);

        //获取发送物流信息，创建返还物流信息
        QueryWrapper<LogisticsInfoEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("logistics_id", orderInfo.getLogisticsSendId());
        LogisticsInfoEntity send = logisticsInfoDao.selectOne(queryWrapper);

        //模拟与物流公司下单，创建运输物流单号
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        formatter.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        String str = formatter.format(new Date());
        int ran = new Random().nextInt(100);
        String logisticsNo = "MMWL" + str + String.format("%02d", ran);

        LogisticsInfoEntity back = new LogisticsInfoEntity();
        back.setLogisticsNo(logisticsNo);
        back.setOrderId(send.getOrderId());
        back.setEndAddress(send.getStartAddress());
        back.setStartAddress(send.getEndAddress());

        //创建物流订单
        int backId = logisticsFeign.addLogisticsOrder(back);
        orderInfo.setLogisticsBackId(backId);

        //更新订单状态
        UpdateWrapper<LeaseOrderEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_id", orderId);
        leaseOrderDao.update(orderInfo, updateWrapper);

        return true;
    }

    //转租为买
    @Override
    public boolean changeToBuy(String orderId) {
        LeaseOrderEntity orderInfo = orderInfoService.getOrderInfo(orderId);
        GoodsEntity goodsInfo = getGooods(orderInfo.getGoodsId());

        if (goodsInfo.getIsAllowedBuy() == 0) {
            return false;
        }

        orderInfo.setOrderState(5);

        //计算实际押金\租赁费用\租赁物原价
        float sumRent = goodsInfo.getGoodsRent() * orderInfo.getOrderNum();
        float sumDeposit = orderInfo.getOrderCost() - sumRent;
        float sumPrice = goodsInfo.getGoodsPrice() * orderInfo.getOrderNum();
        float cost = orderInfo.getOrderCost();

        float pay;
        float backMoney;
        if (cost > sumPrice) {
            pay = (float)(sumPrice*0.9);
            backMoney = cost -pay;
        } else {
            if (sumDeposit > 0) {
                pay = (float)(sumPrice*0.9);
                backMoney = cost -pay;
            }
            else {
                pay = (float)(sumPrice*0.85);
                backMoney = cost -pay;
            }
        }
        String str = "订单"+orderInfo.getOrderId()+" 转租为买";

        PaymentDto paymentDto = setPayment(orderInfo.getBuyerId(),backMoney,str,10);
        paymentAndCreditFeign.payAmount(paymentDto);

        paymentDto = setPayment(orderInfo.getShopId(),pay,str,11);
        paymentAndCreditFeign.payAmount(paymentDto);

        //更新订单状态
        UpdateWrapper<LeaseOrderEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_id",orderId);

        leaseOrderDao.update(orderInfo,updateWrapper);

        //更新租户信用
        paymentAndCreditFeign.updateBuyerCreditScore(orderId);


        return true;
    }

    @Override
    public boolean refund(String orderId) {

        LeaseOrderEntity orderInfo = orderInfoService.getOrderInfo(orderId);

        if (orderInfo.getOrderState() != 11) {
            return false;
        }
        String str = "订单"+orderInfo.getOrderId()+" 退款";
        PaymentDto paymentDto = setPayment(orderInfo.getBuyerId(),orderInfo.getOrderCost(),str,10);

        //更新订单状态，并退款
        paymentAndCreditFeign.payAmount(paymentDto);

        orderInfo.setOrderState(8);
        UpdateWrapper<LeaseOrderEntity> leaseOrderEntityUpdateWrapper = new UpdateWrapper<>();
        leaseOrderEntityUpdateWrapper.eq("order_id",orderId);
        leaseOrderDao.update(orderInfo,leaseOrderEntityUpdateWrapper);
        return true;
    }

    @Override
    public boolean shipAgain(String orderId) {

        LeaseOrderEntity orderInfo = orderInfoService.getOrderInfo(orderId);

        if (orderInfo.getOrderState() != 11) {
            return false;
        }

        //获取发送物流信息，创建新物流信息
        QueryWrapper<LogisticsInfoEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("logistics_id", orderInfo.getLogisticsSendId());
        LogisticsInfoEntity send = logisticsInfoDao.selectOne(queryWrapper);

        //模拟与物流公司下单，创建运输物流单号
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        formatter.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        String str = formatter.format(new Date());
        int ran = new Random().nextInt(100);
        String logisticsNo = "MMWL" + str + String.format("%02d", ran);

        LogisticsInfoEntity newOne = new LogisticsInfoEntity();
        newOne.setLogisticsNo(logisticsNo);
        newOne.setOrderId(send.getOrderId());
        newOne.setEndAddress(send.getEndAddress());
        newOne.setStartAddress(send.getStartAddress());

        //创建物流订单
        int sendId = logisticsFeign.addLogisticsOrder(newOne);

        orderInfo.setLogisticsSendId(sendId);
        orderInfo.setOrderState(0);

        //更新订单状态
        UpdateWrapper<LeaseOrderEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_id",orderId);

        leaseOrderDao.update(orderInfo,updateWrapper);


        return true;
    }
}
